#include "client.h"

//===============================================================
// Initializes a new client.
//===============================================================
CClient::CClient(CLIENTINFO *pInfo) : m_pInfo(pInfo)
{
}

//===============================================================
// Updates the client by processing incoming data and 
// executing timed events.
//===============================================================
void CClient::Update()
{
	while (m_pInfo->buf_in_pos >= 2)
	{
		u_int nLen = (m_pInfo->buf_in[0] << 8) | m_pInfo->buf_in[1];
		if ((nLen + 2) >= m_pInfo->buf_in_pos)
		{
			if (nLen > 0)
			{
				CPacket *pPacket = new CPacket(m_pInfo->buf_in + 2, nLen);
				Handle(pPacket);

				delete pPacket;
			}

			u_int nBytesLeft = m_pInfo->buf_in_pos - (nLen + 2);
			if (nBytesLeft > 0)
			{
				//memmove(m_pInfo->buf_in, m_pInfo->buf_in + nLen + 2, nBytesLeft);
				memcpy(m_pInfo->buf_in, m_pInfo->buf_in + nLen + 2, nBytesLeft);
			}
			m_pInfo->buf_in_pos -= (nLen + 2);
		}
		else break;
	}
}

//===============================================================
// Handles the specified packet.
//===============================================================
void CClient::Handle(CPacket *pPacket)
{
	bool result = false;
	switch (pPacket->ReadShort())
	{
		case PMC_IDENTIFY:	result = MSG_Identify(pPacket);	break;
		case PMC_LOGIN:		result = MSG_Login(pPacket);	break;
		case PMC_MOVE:		result = MSG_Move(pPacket);		break;
	}

	/* Disconnect the client if handling the packet failed. */
	if (!result)
	{
	}
}

//===============================================================
// Sends the specified packet to the client.
//===============================================================
void CClient::Send(u_short nMsg, CPacket *pPacket)
{
	if (!pPacket)
		return;

	/* Write packet size to the buffer. */
	u_int nLen = pPacket->GetContentSize() + 2;
	m_pInfo->buf_out[m_pInfo->buf_out_pos] = ((nLen & 0xFF00) >> 8);
	m_pInfo->buf_out[m_pInfo->buf_out_pos + 1] = (nLen & 0xFF);

	/* Write the packet to the outgoing data buffer. */
	m_pInfo->buf_out[m_pInfo->buf_out_pos + 2] = ((nMsg & 0xFF00) >> 8);
	m_pInfo->buf_out[m_pInfo->buf_out_pos + 3] = (nMsg & 0xFF);
	memcpy(m_pInfo->buf_out + m_pInfo->buf_out_pos + 4, pPacket->GetData(), nLen);
	m_pInfo->buf_out_pos += nLen + 2;
}
